package cn.jdemo.jsystem.runtime;

/**
 * @see Runtime#gc() 运行垃圾收集器。 *调用此方法表明Java虚拟机花费了*努力回收未使用的对象，以使内存*它们当前占用的内存可用于快速重用。当控件从方法调用返回时，虚拟机将尽最大努力回收所有丢弃的对象
 *
 * 前提:
 * Vm Options:-Xms64m -Xmx64m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
 *
 * 须知:
 * (1)Java中Stop-The-World机制简称STW，是在执行垃圾收集算法时，Java应用程序的其他所有线程都被挂起（除了垃圾收集帮助器之外）
 *
 * (2)[GC (Allocation Failure) [PSYoungGen: 16384K->847K(18944K)] 16384K->855K(62976K), 0.0207576 secs] [Times: user=0.00 sys=0.00, real=0.02 secs]
 *     GC：前面没有Full修饰，表明这是一次Minor GC
 *     Allocation Failure：表明本次GC是因为在年轻代中没有足够的空间能够存储新的数据了
 *
 *     PSYoungGen(Young area)：年轻代收集算法(分代收集算法，其他PSOldGen 及Tenured area(也就是PSPermGen)中)
 *     // ParNew：表明本次GC发生在年轻代并且使用的是ParNew垃圾收集器。ParNew是一个Serial收集器的多线程版本，会使用多个CPU和线程完成垃圾收集工作（默认使用的线程数和CPU数相同，可以使用-XX：ParallelGCThreads参数限制）。该收集器采用复制算法回收内存，期间会停止其他工作线程，即Stop The World。
 *     16384K->847K(18944K)：三个参数分别为：GC前该内存区域(这里是年轻代)使用容量，GC后该内存区域使用容量，该内存区域总容量。
 *
 *     522739K->156516K(1322496K)：三个参数分别为：堆区垃圾回收前的大小，堆区垃圾回收后的大小，堆区总大小。
 *     0.0025301 secs：该内存区域GC耗时,单位是秒
 *
 *     [Times: user=0.00 sys=0.00, real=0.02 secs]：分别表示用户态耗时，内核态耗时和总耗时
 * (2)2020-12-24T13:34:29.067+0800: 0.210: [GC (Allocation Failure) [PSYoungGen: 20184K->0K(20480K)] 20192K->724K(64512K), 0.0010053 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
 *      GC (Allocation Failure)
 *      PSYoungGen: 20184K->0K(20480K)
 *
 *
 * @date 2020/12/18
 */
public class Demo06_gc {
    public static void main(String[] args) {
        test01();
    }

    /**
     * 输出内容:
     * processors:4
     * maxMemory:61m
     * totalMemory:61m
     * freeMemory:58m
     *
     * 2020-12-24T13:29:57.204+0800: 0.282: [GC (Allocation Failure) [PSYoungGen: 16384K->847K(18944K)] 16384K->855K(62976K), 0.0207576 secs] [Times: user=0.00 sys=0.00, real=0.02 secs]
     * ... ...
     * 2020-12-24T13:34:29.067+0800: 0.210: [GC (Allocation Failure) [PSYoungGen: 20184K->0K(20480K)] 20192K->724K(64512K), 0.0010053 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
     * ... ...
     * ---------------------
     * processors:4
     * maxMemory:63m
     * totalMemory:63m
     * freeMemory:50m
     * Heap
     *  PSYoungGen      total 20992K, used 13107K [0x00000000feb00000, 0x0000000100000000, 0x0000000100000000)
     *   eden space 20480K, 64% used [0x00000000feb00000,0x00000000ff7ccd90,0x00000000fff00000)
     *   from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
     *   to   space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
     *  ParOldGen       total 44032K, used 724K [0x00000000fc000000, 0x00000000feb00000, 0x00000000feb00000)
     *   object space 44032K, 1% used [0x00000000fc000000,0x00000000fc0b5070,0x00000000feb00000)
     *  Metaspace       used 3292K, capacity 4556K, committed 4864K, reserved 1056768K
     *   class space    used 348K, capacity 392K, committed 512K, reserved 1048576K
     *
     */
    public static void test01() {
        printMem();
        int i=0;
        while (i<=100000000){
            i++;
            String s = new String();
        }
        System.out.println("---------------------");
        printMem();
    }
    private static void printMem(){
        int processors = Runtime.getRuntime().availableProcessors();
        long totalMemory = Runtime.getRuntime().totalMemory();
        long maxMemory = Runtime.getRuntime().maxMemory();// -Xmx64m
        long freeMemory = Runtime.getRuntime().freeMemory();
        System.out.println("processors:" + processors);
        System.out.println("maxMemory:" + maxMemory/(1024*1024)+"m");
        System.out.println("totalMemory:" + totalMemory/(1024*1024)+"m");
        System.out.println("freeMemory:" + freeMemory/(1024*1024)+"m");
    }

}
